function [Ptrans,TransMat] = kneu_prepca(P, N_or_min_frac)
%PREPCA Principal component analysis.
%  
%  Syntax
%
%    [ptrans,transMat] = kneu_prepca(P,N_or_min_frac)
%
%  Description
%  
%    PREPCA preprocesses an input training
%    set by applying a principal component analysis.
%     This analysis transforms the input data so that
%     the elements of the input vectors will be uncorrelated.
%     In addition, the size of the input vectors may be
%     reduced by retaining only those components which
%     contribute more than a specified fraction (N_or_min_frac) of the
%     total variation in the data set. If N_or_min_frac is an integer
%     the first N_or_min_frac components are retained.
%  
%    PREPCA(p,N_or_min_frac) takes these inputs:
%      P        - RxQ matrix of centered input (column) vectors.
%      N_or_min_frac - Minimum fraction variance component to keep 
%                       or number of components to keep.
%    and returns:
%       Ptrans   - Transformed data set.
%       TransMat - Transformation matrix.
%
%  See PREPCA for more details.  
%  See also PRESTD, PREMNMX, TRAPCA.
%
%   References
%
%     Jolliffe, Principal Component Analysis, Springer, 1986.

% modified by Klinik f�r Neurologie II, Magdeburg, Germany
% Copyright 1992-2002 The MathWorks, Inc.

[R,Q]=size(P);

% if  R > Q, warning('Input matrix has more rows than columns.'); end  

% Use the singular value decomposition to compute the principal components
[TransMat,s,v] = svd(P,0);

% Compute the variance of each principal component
var = diag(s).^2/(Q-1);

% Compute total variance and fractional variance
total_variance = sum(var);
frac_var = var./total_variance;

if N_or_min_frac < 1,
    % Find the componets which contribute more than N_or_min_frac of the total variance
    greater = (frac_var > N_or_min_frac);
    size_pc = sum(greater);

    % Reduce the transformation matrix appropriately
    TransMat = TransMat(:,1:size_pc)';
elseif round(N_or_min_frac)==N_or_min_frac, 
    TransMat = TransMat(:,1:N_or_min_frac)';
else 
    error('2nd input argument is corrupt');
end

% Transform the data
Ptrans = TransMat*P;

